using System;

using Microsoft.SPOT;

using mfLogger;
using mfXmlSerializer;
using mfRCF.Core;
using mfRCF.Core.Extensions;

using OST.Persistence;

namespace OST.Commands.Extensions
{
    public static class RcfExtensions
    {        
        /// <summary>
        /// wrapper-property 4 logging
        /// </summary>
        private static ILoggerAppender Logger
        {
            get
            {
                return mfLogger.mfLogger.Instance;
            }
        }

        public static void WriteHttpResponseError(this mfRcfCommand cmd, mfIHttpContext httpContext, Exception ex)
        {
            Debug.GC(true);
            Logger.Error(ex);
            httpContext.Response.ContentType = "text/plain";
            httpContext.Response.StatusCode = enumHttpStatusCode.InternalServerError;
            httpContext.Response.WriteString(ex.Message);
            httpContext.Response.Close();
        }

        public static void WriteHttpResponseOK(this mfRcfCommand cmd, mfIHttpContext httpContext, string msg = null)
        {
            httpContext.Response.ContentType = "text/plain";
            httpContext.Response.StatusCode = enumHttpStatusCode.OK;
            if (msg != null) httpContext.Response.WriteString(msg);

            httpContext.Response.Close();

            Logger.Debug(cmd.GetType() + " executed, " + Debug.GC(false) + " bytes free");
        }

        public static void ApplyConfigChanges(this mfRcfCommand cmd, mfIHttpContext httpContext, mfXmlTypedSerializer serializer, Object targetOfInvocation)
        {
            var parameters = httpContext.Request.RawUrl.ExtractUrlParameter();
            bool setExecuted = false;
            foreach (var paraKey in parameters.Keys)
            {
                foreach (mfMapBaseElement serEle in serializer.SerializationMap.SerializationElements)
                {
                    if (serEle.Name.Equals(paraKey.ToString()))
                    {
                        var newStringValue = parameters[paraKey].ToString();
                        serEle.ExecuteSet(targetOfInvocation, newStringValue);
                        Logger.Info("config-updated " + paraKey + " with " + newStringValue);
                        setExecuted = true;
                        continue;
                    }
                }
            }

            //persist new config
            if (setExecuted)
            {
                ConfigurationProvider.Instance.SaveConfiguration();
                cmd.WriteHttpResponseOK(httpContext, "saved (not applied)");
            }
            else
            {
                cmd.WriteHttpResponseOK(httpContext, "nothing saved, check parameters");
            }
        }

    }
}
